In [1]:
import os

!pip install wget
if not os.path.exists('thinkdsp.py'):
    !python -m wget https://github.com/AllenDowney/ThinkDSP/raw/master/code/thinkdsp.py

import numpy as np
import matplotlib.pyplot as plt

from thinkdsp import decorate
Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/
Collecting wget
  Downloading wget-3.2.zip (10 kB)
  Preparing metadata (setup.py) ... done
Building wheels for collected packages: wget
  Building wheel for wget (setup.py) ... done
  Created wheel for wget: filename=wget-3.2-py3-none-any.whl size=9676 sha256=3a4891047f2949af9819354d22e31670d7337f937371c0cb66aa9c4fc975a9e7
  Stored in directory: /root/.cache/pip/wheels/8b/f1/7f/5c94f0a7a505ca1c81cd1d9208ae2064675d97582078e6c769
Successfully built wget
Installing collected packages: wget
Successfully installed wget-3.2

Saved under thinkdsp.py

Упражнение 11.3¶

Выше показано, что при взятии выборок из сигнала при слишком низкой частоте кадров составляющие, большие частоты заворота дадут биения. В таком случае эти компоненты не отфильтруешь, поскольку они неотличимы от более низких частот.

Полезно отфильтровать эти частоты до выборки; фильтр НЧ, используемый для этой цели, называется фильтр сглаживания.

Вернитесь к примеру «Соло на барабане», примените фильтр НЧ до выборки, а затем, опять же с помощью фильтра НЧ, удалите спектральные копии, вызванные выборкой. Результат должен быть идентичен отфильтрованному сигналу.

In [2]:
if not os.path.exists('263868__kevcio__amen-break-a-160-bpm.wav'):
    !python -m wget https://github.com/AllenDowney/ThinkDSP/raw/master/code/263868__kevcio__amen-break-a-160-bpm.wav
Saved under 263868__kevcio__amen-break-a-160-bpm.wav
In [3]:
from thinkdsp import read_wave

wave = read_wave('263868__kevcio__amen-break-a-160-bpm.wav')
wave.plot()
In [5]:
wave.framerate
Out[5]:
44100
In [4]:
wave.make_audio()
Out[4]:
Your browser does not support the audio element.
In [6]:
spectrum = wave.make_spectrum(full=True)
spectrum.plot()

Фильтр НЧ:

In [7]:
factor = 3
framerate = wave.framerate / factor
cutoff = framerate / 2 - 1
In [8]:
spectrum.low_pass(cutoff)
spectrum.plot()
In [9]:
filtered = spectrum.make_wave()
filtered.make_audio()
Out[9]:
Your browser does not support the audio element.

Функция из chap11.ipynb:

In [10]:
from thinkdsp import Wave

def sample(wave, factor):
    """Simulates sampling of a wave.
    
    wave: Wave object
    factor: ratio of the new framerate to the original
    """
    ys = np.zeros(len(wave))
    ys[::factor] = wave.ys[::factor]
    return Wave(ys, framerate=wave.framerate) 
In [11]:
sampled = sample(filtered, factor)
sampled.make_audio()
<ipython-input-10-c09601fcf680>:10: ComplexWarning: Casting complex values to real discards the imaginary part
  ys[::factor] = wave.ys[::factor]
Out[11]:
Your browser does not support the audio element.
In [12]:
sampled_spectrum = sampled.make_spectrum(full=True)
sampled_spectrum.plot()

Избавляемся от спектральных копий:

In [13]:
sampled_spectrum.low_pass(cutoff)
sampled_spectrum.plot()
In [14]:
interpolated = sampled_spectrum.make_wave()
interpolated.make_audio()
Out[14]:
Your browser does not support the audio element.

Аудиозапись идентична с записью отфильтрованной по НЧ

In [15]:
spectrum.plot()
sampled_spectrum.plot()

Только амплитуды не равны, исправим это

In [16]:
sampled_spectrum.scale(factor)
sampled_spectrum.plot()
spectrum.plot()
In [17]:
interpolated = sampled_spectrum.make_wave()
interpolated.make_audio()
Out[17]:
Your browser does not support the audio element.

Теперь звуки действительно неотличимы.